using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using GameLib.Enums;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GameLib.Managers
{
    public delegate void BoardDelegate(object sender, EventArgs e);

    public class InputManager
    {
        Texture2D infoBox; // Picture of the Information Box
        Rectangle infoBoxPosition;
        SpriteFont infoFont;

        Texture2D btnPause;
        Texture2D btnSound;
        Texture2D btnNotMute;
        Texture2D btnMute;
        Texture2D btnFastForward;
        Texture2D btnFastForward_Active;
        Texture2D btnFastForward_NotActive;
        Rectangle btnPausePosition;
        Rectangle btnSoundAndMutePosition;
        Rectangle btnFastForwardPosition;
        Color btnPauseColor;
        Color btnSoundColor;
        Color btnMuteColor;
        Color btnFastForwardColor;
        PressedButton pressedButton;

        SoundEffect sound_btnPressed;
        SoundEffect sound_btnReleased;

        MouseState currentMouseState;
        MouseState lastMouseState;

        PieceManager pieceMgr;

        Texture2D backgroundFromCamera;

        Keys movingKey;

        bool gameIsFinished = false;

        bool inputAvailible;

        public event EventHandler GameFinished;
        public event EventHandler GameStarted;
        public event EventHandler GamePaused;
        public event EventHandler UserMovedPiece;
        public event EventHandler FastForward;

        private int msSinceLastMove;
        private int moveSpeed = 1;

        public InputManager(ContentManager content)
        {
            //matrix = new Vector2[4, 4];
            //spriteSize = new Point(150, 94);
            //tron = content.Load<Texture2D>("tron");
            infoBox = content.Load<Texture2D>("selectRectangle");
            infoBoxPosition = new Rectangle(160, 100, 400, 200);
            infoFont = content.Load<SpriteFont>("MenuFont");

            btnPause = content.Load<Texture2D>("btn-pause-small");

            btnNotMute = content.Load<Texture2D>("btn-sound-small");
            btnMute = content.Load<Texture2D>("btn-mute-small");
            btnSound = btnNotMute;

            btnFastForward_Active = content.Load<Texture2D>("btn-fastforward-small");
            btnFastForward_NotActive = content.Load<Texture2D>("btn-fastforward-small-notActive");
            btnFastForward = btnFastForward_NotActive;
            //fastForwardActive = false;

            btnPausePosition = new Rectangle(50, 120, 50, 50);
            btnSoundAndMutePosition = new Rectangle(50, 180, 50, 50);
            btnFastForwardPosition = new Rectangle(50, 240, 50, 50);
            btnPauseColor = Color.White;
            btnSoundColor = Color.White;
            btnMuteColor = Color.White;
            btnFastForwardColor = Color.White;
            pressedButton = PressedButton.None;

            sound_btnPressed = content.Load<SoundEffect>("btnPressed");
            sound_btnReleased = content.Load<SoundEffect>("btnReleased");

            currentMouseState = Mouse.GetState();
            lastMouseState = Mouse.GetState();

            movingKey = Keys.None;

            inputAvailible = false;

            pieceMgr = new PieceManager(content);
            pieceMgr.GameFinished += new EventHandler(pieceMgr_GameFinished);
            pieceMgr.ShuffleFinished += new EventHandler(pieceMgr_ShuffleFinished);

            //scoreMgr = new ScoreManager();

        }

        public void setBackgroundFromCamera(Texture2D fromCamera)
        {
            //backgroundFromCamera = fromCamera;
            pieceMgr.UpdateBackground(fromCamera);
        }

        private void pieceMgr_ShuffleFinished(object sender, EventArgs e)
        {
            Debug.WriteLine("Board: GameStarted!");
            btnFastForward = btnFastForward_Active;
            if (GameStarted != null)
                GameStarted(this, new EventArgs());
            inputAvailible = true;
        }

        private void pieceMgr_GameFinished(object sender, EventArgs e)
        {
            Debug.WriteLine("Board: GameFinished!");
            if (GameFinished != null)
                GameFinished(this, new EventArgs());
            //scoreMgr.StopTime();
            inputAvailible = false;
            gameIsFinished = true;
        }

        public void OnUpdate(TimeSpan elapsedGameTime)
        {
            
            lastMouseState = currentMouseState;
            currentMouseState = Mouse.GetState();

            if (inputAvailible)
            {
                var moveMade = false;
                if (movingKey == Keys.None) // No Movement is being made
                {
                    if (Keyboard.GetState().IsKeyDown(Keys.Right))
                    {
                        moveMade = pieceMgr.MovePiece(Direction.Right);
                        movingKey = Keys.Right;
                    }
                    else if (Keyboard.GetState().IsKeyDown(Keys.Left))
                    {
                        moveMade = pieceMgr.MovePiece(Direction.Left);
                        movingKey = Keys.Left;
                    }
                    else if (Keyboard.GetState().IsKeyDown(Keys.Up))
                    {
                        moveMade = pieceMgr.MovePiece(Direction.Up);
                        movingKey = Keys.Up;
                    }
                    else if (Keyboard.GetState().IsKeyDown(Keys.Down))
                    {
                        moveMade = pieceMgr.MovePiece(Direction.Down);
                        movingKey = Keys.Down;
                    }
                }
                else // Check if movement key has been released
                    if (Keyboard.GetState().IsKeyUp(movingKey))
                        movingKey = Keys.None;

                if (currentMouseState.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
                {
                    moveMade = pieceMgr.MovePieceWithMouse(new Vector2(Mouse.GetState().X, Mouse.GetState().Y));
                }

                if (moveMade)
                {
                    Debug.WriteLine("Board: UserMovedPiece!");
                    if (UserMovedPiece != null)
                        UserMovedPiece(this, new EventArgs());
                }

                InitButtonPosition(elapsedGameTime);
            }



            CheckIfMousePointerIsHooveringButton();

            if (currentMouseState.LeftButton == ButtonState.Pressed)
                CheckIfMousePressedButton(new Rectangle(Mouse.GetState().X + 15, Mouse.GetState().Y, 2, 2));


            if (Mouse.GetState().LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)
                CheckIfMouseReleasedButton(new Rectangle(Mouse.GetState().X + 15, Mouse.GetState().Y, 2, 2));


            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                PauseGame();
            }

            if (!gameIsFinished)
                pieceMgr.Update(elapsedGameTime);

        }

        private void PauseGame()
        {
            Debug.WriteLine("Board: GamePaused!");
            if (GamePaused != null)
                GamePaused(this, new EventArgs());
            btnPausePosition.X = -50;
            btnSoundAndMutePosition.X = -50;
            btnFastForwardPosition.X = -50;
        }

        private void InitButtonPosition(TimeSpan elapsedGameTime)
        {
            msSinceLastMove += elapsedGameTime.Milliseconds;
            if (msSinceLastMove > moveSpeed)
            {
                //msSinceLastMove = -50;
                if (btnPausePosition.X < 10)
                {
                    btnPausePosition.X += 2;
                    btnSoundAndMutePosition.X += 2;
                    btnFastForwardPosition.X += 2;
                }

            }
        }

        private void ButtonInitialState()
        {
            btnPauseColor = Color.White;
            btnSoundColor = Color.White;
            btnMuteColor = Color.White;
            btnFastForwardColor = Color.White;
        }

        private void CheckIfMousePointerIsHooveringButton()
        {
            var mousePosition = new Rectangle(Mouse.GetState().X + 15, Mouse.GetState().Y, 2, 2);

            if (btnPausePosition.Intersects(mousePosition))
                btnPauseColor = Color.LightSkyBlue;
            else
                btnPauseColor = Color.White;

            if (btnSoundAndMutePosition.Intersects(mousePosition))
            {
                btnSoundColor = Color.LightSkyBlue;
                btnMuteColor = Color.LightSkyBlue;
            }
            else
            {
                btnSoundColor = Color.White;
                btnMuteColor = Color.White;
            }

            if (btnFastForwardPosition.Intersects(mousePosition) && btnFastForward == btnFastForward_Active)
                btnFastForwardColor = Color.LightSkyBlue;
            else
                btnFastForwardColor = Color.White;
        }

        private void CheckIfMouseReleasedButton(Rectangle mousePosition)
        {

            if (btnPausePosition.Intersects(mousePosition) && pressedButton == PressedButton.Pause)
            {
                Debug.WriteLine("Clicked on: Pause!");
                if (GamePaused != null)
                    GamePaused(this, new EventArgs());
                sound_btnReleased.Play();
                //scoreMgr.StopTime();
                btnPausePosition.X = -50;
                btnSoundAndMutePosition.X = -50;
                btnFastForwardPosition.X = -50;
            }

            if (btnSoundAndMutePosition.Intersects(mousePosition) && pressedButton == PressedButton.Sound)
            {
                Debug.WriteLine("Clicked on: Sound/Mute!");
                if (SoundEffect.MasterVolume > 0.01f)
                {
                    sound_btnReleased.Play();
                    btnSound = btnMute;
                    SoundEffect.MasterVolume = 0.0f;
                    MediaPlayer.IsMuted = true;
                }
                else
                {
                    btnSound = btnNotMute;
                    SoundEffect.MasterVolume = 1.0f;
                    MediaPlayer.IsMuted = false;
                }



            }

            if (btnFastForwardPosition.Intersects(mousePosition) && pressedButton == PressedButton.FastForward
                && btnFastForward == btnFastForward_Active)
            {
                Debug.WriteLine("Clicked on: FastForward!");
                Debug.WriteLine("Board: FastForward!");
                if (FastForward != null)
                    FastForward(this, new EventArgs());
                pieceMgr.FastForwardPressed();
                inputAvailible = false;
                sound_btnReleased.Play();
                btnFastForward = btnFastForward_NotActive;
                //scoreMgr.StopTime();
            }
        }

        private void CheckIfMousePressedButton(Rectangle mousePosition)
        {
            pressedButton = PressedButton.None;

            if (btnPausePosition.Intersects(mousePosition))
            {
                btnPauseColor = Color.LightSeaGreen;
                pressedButton = PressedButton.Pause;
            }

            else
                btnPauseColor = Color.White;

            if (btnSoundAndMutePosition.Intersects(mousePosition))
            {
                btnSoundColor = Color.LightSeaGreen;
                btnMuteColor = Color.LightSeaGreen;
                pressedButton = PressedButton.Sound;
            }
            else
            {
                btnSoundColor = Color.White;
                btnMuteColor = Color.White;
            }

            if (btnFastForwardPosition.Intersects(mousePosition) && btnFastForward == btnFastForward_Active)
            {
                btnFastForwardColor = Color.LightSeaGreen;
                pressedButton = PressedButton.FastForward;
            }

            else
                btnFastForwardColor = Color.White;

            if (pressedButton != PressedButton.None &&
                currentMouseState.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released)
                sound_btnPressed.Play();
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            pieceMgr.Draw(spriteBatch);
            //if (gameIsFinished)
            //{
            //    spriteBatch.Draw(infoBox, infoBoxPosition, Color.LightBlue * 0.8f);
            //    spriteBatch.DrawString(infoFont, "Game Finished!\n\nYour time is: "+ scoreMgr.Time +"\nYou made "+ scoreMgr.Moves +" moves", new Vector2(infoBoxPosition.X + 20, infoBoxPosition.Y + 20), Color.Yellow);
            //}
            spriteBatch.Draw(btnPause, btnPausePosition, btnPauseColor);
            spriteBatch.Draw(btnSound, btnSoundAndMutePosition, btnSoundColor);
            spriteBatch.Draw(btnFastForward, btnFastForwardPosition, btnFastForwardColor);

            //spriteBatch.DrawString(infoFont, "Time: "+ scoreMgr.Time +"\nMoves: " + scoreMgr.Moves, new Vector2(20, 20), Color.Yellow);

        }

        public void StartGame()
        {
            pieceMgr.FillMatrix();
        }


    }
}
